package workflow

import (
	"bytes"
	"fmt"
	"math"
	"strconv"
	"strings"
	"time"

	"shqsoft.cn/pas3ui/base"
	"shqsoft.cn/pas3ui/popedom"

	"gorm.io/gorm"
)

//CallBackFunc 导入过程中触发的回掉函数
type CallBackFunc func(tx *gorm.DB, runID int, userID int) error

//callBackPool 调入前后的回调池
var callBackPool = make(map[string]CallBackFunc, 10)

//SetFinishCallBack 完成后的回调
func SetFinishCallBack(wfid int, cb CallBackFunc) {
	name := fmt.Sprintf("finish_%d", wfid)
	callBackPool[name] = cb
}

//SetCreateCallBack 创建后的回调
func SetCreateCallBack(wfid int, cb CallBackFunc) {
	name := fmt.Sprintf("create_%d", wfid)
	callBackPool[name] = cb
}

//SetBeforeSubmitCallBack 提交前回调
func SetBeforeSubmitCallBack(wfid int, stepId int, cb CallBackFunc) {
	name := fmt.Sprintf("beforeSubmit_%d_%d", wfid, stepId)
	callBackPool[name] = cb
}

var callBackFuncMap = make(map[string]CallBackFunc, 10)

func CompNewWFCBF(tx *gorm.DB, runID int, userID int) error {
	bdate, err := base.GetBackDATE()
	if err != nil {
		return err
	}
	backdate := bdate.Format("2006-01-02")
	OPDT := time.Now()
	var opdtEx string
	if base.AppConf.Database.Mysql != "" {
		opdtEx = "cast(? as datetime)"
	} else {
		opdtEx = "cast(? as timestamp)"
	}
	sqlstr := fmt.Sprintf(`INSERT INTO "T_COMP_ACCO_DIVI"("ACID","EMID","DSVL","DSDT","DSEM","OPDT")
	SELECT DISTINCT "ACID","EMID","DSVL","DSDT",? "DSEM",%s "OPDT"
		FROM (SELECT A."ACID" "ACID",A."EMID1" "EMID",A."DSVL1"/100 "DSVL",CASE WHEN A."OPDT" < ? THEN ? ELSE A."OPDT" END "DSDT"
				FROM "T_COMP_CLIE_DIVI" A INNER JOIN "T_FLOW_RUN_STEP" S ON A."FRID"=S."RUNID"
				WHERE S."EMID"=? AND A."FRID"=? AND A."DSVL1">0 and A."EMID1">0
		UNION ALL
		SELECT A."ACID",A."EMID2" "EMID",A."DSVL2"/100 "DSVL",CASE WHEN A."OPDT" < ? THEN ? ELSE A."OPDT" END "DSDT"
				FROM "T_COMP_CLIE_DIVI" A INNER JOIN "T_FLOW_RUN_STEP" S ON A."FRID"=S."RUNID"
				WHERE S."EMID"=? AND A."FRID"=? AND A."DSVL2">0 and A."EMID2">0
		UNION ALL
		SELECT A."ACID",A."EMID3" "EMID",A."DSVL3"/100 "DSVL",CASE WHEN A."OPDT" < ? THEN ? ELSE A."OPDT" END "DSDT"
				FROM "T_COMP_CLIE_DIVI" A INNER JOIN "T_FLOW_RUN_STEP" S ON A."FRID"=S."RUNID"
				WHERE S."EMID"=? AND A."FRID"=? AND A."DSVL3">0 and A."EMID3">0
		UNION ALL
		SELECT A."ACID",A."EMID4" "EMID",A."DSVL4"/100 "DSVL",CASE WHEN A."OPDT" < ? THEN ? ELSE A."OPDT" END "DSDT"
				FROM "T_COMP_CLIE_DIVI" A INNER JOIN "T_FLOW_RUN_STEP" S ON A."FRID"=S."RUNID"
				WHERE S."EMID"=? AND A."FRID"=? AND A."DSVL4">0 and A."EMID4">0
		) A`, opdtEx)
	err = tx.Exec(sqlstr, strconv.Itoa(userID), OPDT, backdate, backdate, userID, runID, backdate, backdate, userID, runID, backdate, backdate, userID, runID, backdate, backdate, userID, runID).Error
	if err != nil {
		return err
	}
	var acid, emid1, emid2, emid3 int
	var dsvl1, dsvl2, dsvl3 float64
	sqlstr = `select "ACID","EMID1" ,"DSVL1","EMID2" ,"DSVL2","EMID3" ,"DSVL3"  from "T_COMP_CLIE_DIVI" where "FRID"=?`
	err = tx.Raw(sqlstr, runID).Row().Scan(&acid, &emid1, &dsvl1, &emid2, &dsvl2, &emid3, &dsvl3)
	if err != nil {
		return err
	}
	err = base.SetDiviMap(base.Comp, acid, emid1, dsvl1, emid2, dsvl2, emid3, dsvl3)
	if err != nil {
		return err
	}
	var tableName = "T_COMP_CLIE_DIVI"
	var tableNameHis = "T_COMP_CLIE_DIVI_HIS"
	err = InsertHistory(tx, runID, tableName, tableNameHis)
	if err != nil {
		return err
	}
	sqlstr = `INSERT INTO JOIN_COMP_ACCO_ISDIVI(ACID,ISRD)
	SELECT ? ACID,1 ISRD`
	base.CHDB.Exec(sqlstr, acid)
	return nil
}

func InsertHistory(tx *gorm.DB, runID int, tableName, tableNameHis string) error {
	sqlStr := fmt.Sprintf(`INSERT INTO "%s" SELECT * FROM "%s" WHERE "FRID"=%d`, tableNameHis, tableName, runID)
	err := tx.Exec(sqlStr).Error
	if err != nil {
		return err
	}
	sqlStr = `INSERT INTO "T_FLOW_RUN_HIS" SELECT * FROM "T_FLOW_RUN" WHERE "ID"=?`
	err = tx.Exec(sqlStr, runID).Error
	if err != nil {
		return err
	}
	sqlStr = `INSERT INTO "T_FLOW_RUN_STEP_HIS" SELECT * FROM "T_FLOW_RUN_STEP" WHERE "RUNID"=?`
	err = tx.Exec(sqlStr, runID).Error
	if err != nil {
		return err
	}
	sqlStr = fmt.Sprintf(`DELETE FROM "%s" WHERE "FRID"=%d`, tableName, runID)
	err = tx.Exec(sqlStr).Error
	if err != nil {
		return err
	}
	sqlStr = `DELETE FROM "T_FLOW_RUN" WHERE "ID"=?`
	err = tx.Exec(sqlStr, runID).Error
	if err != nil {
		return err
	}
	sqlStr = `DELETE FROM "T_FLOW_RUN_STEP" WHERE "RUNID"=?`
	err = tx.Exec(sqlStr, runID).Error
	if err != nil {
		return err
	}
	return nil
}

func CompUpdateWFCBF(tx *gorm.DB, runID int, userID int) error {
	bdate, err := base.GetBackDATE()
	if err != nil {
		return err
	}
	backdate := bdate.Format("2006-01-02")
	OPDT := time.Now()
	var opdtEx, eng string
	if base.AppConf.Database.Mysql != "" {
		eng = "ENGINE=MEMORY DEFAULT CHARSET=utf8;"
		opdtEx = "cast(? as datetime)"
	} else {
		eng = ""
		opdtEx = "cast(? as timestamp)"
	}
	//创建内存表
	sqlstr := fmt.Sprintf(`CREATE TABLE IF NOT EXISTS "TMP_NOZB"(
		"ACID" int,
		"EMID" int,
		"DSVL" decimal(16,4),
		"DSDT" date,
		"DSEM" varchar(20)
	)%s`, eng)
	err = tx.Exec(sqlstr).Error
	if err != nil {
		return err
	}
	sqlstr = `INSERT INTO "TMP_NOZB"("ACID","EMID","DSVL","DSDT","DSEM")
	SELECT DISTINCT "ACID","EMID","DSVL","DSDT",? "DSEM"
		FROM (SELECT A."ACID" "ACID",A."EMID1" "EMID",A."DSVL1"/100 "DSVL",CASE WHEN A."DSDT" < ? THEN ? ELSE A."DSDT" END "DSDT"
				FROM "T_COMP_CLIE_DIVI2" A INNER JOIN "T_FLOW_RUN_STEP" S ON A."FRID"=S."RUNID"
				WHERE S."EMID"=? AND A."FRID"=? AND A."DSVL1">0 and A."EMID1">0
		UNION ALL
		SELECT A."ACID" "ACID",A."EMID2" "EMID",A."DSVL2"/100 "DSVL",CASE WHEN A."DSDT" < ? THEN ? ELSE A."DSDT" END "DSDT"
				FROM "T_COMP_CLIE_DIVI2" A INNER JOIN "T_FLOW_RUN_STEP" S ON A."FRID"=S."RUNID"
				WHERE S."EMID"=? AND A."FRID"=? AND A."DSVL2">0 and A."EMID2">0
		UNION ALL
		SELECT A."ACID" "ACID",A."EMID3" "EMID",A."DSVL3"/100 "DSVL",CASE WHEN A."DSDT" < ? THEN ? ELSE A."DSDT" END "DSDT"
				FROM "T_COMP_CLIE_DIVI2" A INNER JOIN "T_FLOW_RUN_STEP" S ON A."FRID"=S."RUNID"
				WHERE S."EMID"=? AND A."FRID"=? AND A."DSVL3">0 and A."EMID3">0
		UNION ALL
		SELECT A."ACID" "ACID",A."EMID4" "EMID",A."DSVL4"/100 "DSVL",CASE WHEN A."DSDT" < ? THEN ? ELSE A."DSDT" END "DSDT"
				FROM "T_COMP_CLIE_DIVI2" A INNER JOIN "T_FLOW_RUN_STEP" S ON A."FRID"=S."RUNID"
				WHERE S."EMID"=? AND A."FRID"=? AND A."DSVL4">0 and A."EMID4">0
		) A`
	err = tx.Exec(sqlstr, strconv.Itoa(userID), backdate, backdate, userID, runID, backdate, backdate, userID, runID, backdate, backdate, userID, runID, backdate, backdate, userID, runID).Error
	if err != nil {
		return err
	}
	if base.AppConf.Database.Mysql != "" {
		sqlstr = `UPDATE T_COMP_ACCO_DIVI A,TMP_NOZB B
		SET WODT=B.DSDT,ISWO=CASE WHEN A.DSDT<B.DSDT THEN 0 ELSE 1 END
		WHERE A.ACID=B.ACID AND A.ISWO=0 AND (A.WODT IS NULL OR A.WODT>B.DSDT)`
	} else {
		sqlstr = `UPDATE "T_COMP_ACCO_DIVI" A SET "WODT"=B."DSDT","ISWO"=CASE WHEN A."DSDT"<B."DSDT" THEN 0 ELSE 1 END
		from "TMP_NOZB" B
		WHERE A."ACID"=B."ACID" AND A."ISWO"=0 AND (A."WODT" IS NULL OR A."WODT">B."DSDT")`
	}
	err = tx.Exec(sqlstr).Error
	if err != nil {
		return err
	}
	sqlstr = fmt.Sprintf(`INSERT INTO "T_COMP_ACCO_DIVI"("ACID","DSTY","EMID","DSVL","DSDT","DSEM","OPDT")
	SELECT "ACID",1 "DSTY",B."EMID",B."DSVL" "DSVL",B."DSDT","DSEM",%s "OPDT"
	FROM  "TMP_NOZB" B`, opdtEx)
	err = tx.Exec(sqlstr, OPDT).Error
	if err != nil {
		return err
	}
	var acid, emid1, emid2, emid3 int
	var dsvl1, dsvl2, dsvl3 float64
	sqlstr = `select "ACID","EMID1" ,"DSVL1","EMID2" ,"DSVL2","EMID3" ,"DSVL3"  from "T_COMP_CLIE_DIVI2" where "FRID"=?`
	err = tx.Raw(sqlstr, runID).Row().Scan(&acid, &emid1, &dsvl1, &emid2, &dsvl2, &emid3, &dsvl3)
	if err != nil {
		return err
	}
	err = base.SetDiviMap(base.Comp, acid, emid1, dsvl1, emid2, dsvl2, emid3, dsvl3)
	if err != nil {
		return err
	}
	var tableName = "T_COMP_CLIE_DIVI2"
	var tableNameHis = "T_COMP_CLIE_DIVI2_HIS"
	err = InsertHistory(tx, runID, tableName, tableNameHis)
	if err != nil {
		return err
	}
	sqlstr = `DROP TABLE "TMP_NOZB"`
	err = tx.Exec(sqlstr).Error
	if err != nil {
		return err
	}
	return nil
}
func indiClieDiviProc(tx *gorm.DB, runID int, userID int, isNew bool) error {
	bdate, err := base.GetBackDATE("shls")
	if err != nil {
		return err
	}
	var cuid, emid1, emid2, emid3 int
	var dsvl1, dsvl2, dsvl3 float64
	var dsdt *time.Time
	tname := "T_INDI_CLIE_DIVI"
	tnameHis := "T_INDI_CLIE_DIVI_HIS"
	if !isNew {
		tname = "T_INDI_CLIE_DIVI2"
		tnameHis = "T_INDI_CLIE_DIVI2_HIS"
	}
	sqlstr := fmt.Sprintf(`select "CUID","EMID1","DSVL1","EMID2" ,"DSVL2","EMID3","DSVL3","OPDT" from "%s" where "FRID"=?`, tname)
	err = tx.Raw(sqlstr, runID).Row().Scan(&cuid, &emid1, &dsvl1, &emid2, &dsvl2, &emid3, &dsvl3, &dsdt)
	if err != nil {
		return err
	}
	dsvl1 = dsvl1 / 100
	dsvl2 = dsvl2 / 100
	dsvl3 = dsvl3 / 100
	if dsdt == nil || dsdt.Unix() < bdate.Unix() {
		dsdt = bdate
	}
	sqlstr = "select ID from T_INDI_ACCO where CUID=?"
	rows, err := base.CHDB.Raw(sqlstr, cuid).Rows()
	if err != nil {
		return err
	}
	defer rows.Close()
	acids := make([]int, 0, 10)
	for rows.Next() {
		var acid int
		rows.Scan(&acid)
		acids = append(acids, acid)
	}
	sqlstr = `UPDATE "T_INDI_ACCO_DIVI" SET "WODT"=?,"ISWO"=CASE WHEN "DSDT"<? THEN 0 ELSE 1 END
		      WHERE ACID in (?) AND "ISWO"=0 AND ("WODT" IS NULL OR "WODT">?)`
	err = tx.Exec(sqlstr, dsdt, dsdt, acids, dsdt).Error
	if err != nil {
		return err
	}
	for _, acid := range acids {
		sqlstr = `INSERT INTO "T_INDI_ACCO_DIVI"("ACID","EMID","DSVL","DSDT","DSEM","OPDT") VALUES (?,?,?,?,?,?)`
		if emid1 > 0 && dsvl1 > 0 {
			err = tx.Exec(sqlstr, acid, emid1, dsvl1, dsdt, userID, time.Now()).Error
			if err != nil {
				return err
			}
		}
		if emid2 > 0 && dsvl2 > 0 {
			err = tx.Exec(sqlstr, acid, emid2, dsvl2, dsdt, userID, time.Now()).Error
			if err != nil {
				return err
			}
		}
		if emid3 > 0 && dsvl3 > 0 {
			err = tx.Exec(sqlstr, acid, emid3, dsvl3, dsdt, userID, time.Now()).Error
			if err != nil {
				return err
			}
		}
	}
	err = base.SetDiviMap(base.IndiClie, cuid, emid1, dsvl1, emid2, dsvl2, emid3, dsvl3)
	if err != nil {
		return err
	}
	err = InsertHistory(tx, runID, tname, tnameHis)
	return err
}
func IndiSaveNewWFCBF(tx *gorm.DB, runID int, userID int) error {
	return indiClieDiviProc(tx, runID, userID, true)
}
func IndiSaveUpdateWFCBF(tx *gorm.DB, runID int, userID int) error {
	return indiClieDiviProc(tx, runID, userID, false)
}
func IndiLoanNewWFCBF(tx *gorm.DB, runID int, userID int) error {
	bdate, err := base.GetBackDATE()
	if err != nil {
		return err
	}
	backdate := bdate.Format("2006-01-02")
	OPDT := time.Now()
	var opdtEx string
	if base.AppConf.Database.Mysql != "" {
		opdtEx = "cast(? as datetime)"
	} else {
		opdtEx = "cast(? as timestamp)"
	}
	sqlstr := fmt.Sprintf(`INSERT INTO "T_INDI_LOAN_DIVI"("ACID","EMID","DSVL","DSDT","DSEM","OPDT")
	SELECT DISTINCT "ACID","EMID","DSVL","DSDT",? "DSEM",%s "OPDT"
		FROM (SELECT A."ACID" "ACID",A."EMID1" "EMID",A."DSVL1"/100 "DSVL",CASE WHEN A."OPDT" < ? THEN ? ELSE A."OPDT" END "DSDT"
				FROM "T_INDI_CLIE_LOAN_DIVI" A INNER JOIN "T_FLOW_RUN_STEP" S ON A."FRID"=S."RUNID"
				WHERE S."EMID"=? AND A."FRID"=? AND A."DSVL1">0 and A."EMID1">0
		UNION ALL
		SELECT A."ACID" "ACID",A."EMID2" "EMID",A."DSVL2"/100 "DSVL",CASE WHEN A."OPDT" < ? THEN ? ELSE A."OPDT" END "DSDT"
				FROM "T_INDI_CLIE_LOAN_DIVI" A INNER JOIN "T_FLOW_RUN_STEP" S ON A."FRID"=S."RUNID"
				WHERE S."EMID"=? AND A."FRID"=? AND A."DSVL2">0 and A."EMID2">0
		UNION ALL
		SELECT A."ACID" "ACID",A."EMID3" "EMID",A."DSVL3"/100 "DSVL",CASE WHEN A."OPDT" < ? THEN ? ELSE A."OPDT" END "DSDT"
				FROM "T_INDI_CLIE_LOAN_DIVI" A INNER JOIN "T_FLOW_RUN_STEP" S ON A."FRID"=S."RUNID"
				WHERE S."EMID"=? AND A."FRID"=? AND A."DSVL3">0 and A."EMID3">0
		UNION ALL
		SELECT A."ACID" "ACID",A."EMID4" "EMID",A."DSVL4"/100 "DSVL",CASE WHEN A."OPDT" < ? THEN ? ELSE A."OPDT" END "DSDT"
				FROM "T_INDI_CLIE_LOAN_DIVI" A INNER JOIN "T_FLOW_RUN_STEP" S ON A."FRID"=S."RUNID"
				WHERE S."EMID"=? AND A."FRID"=? AND A."DSVL4">0 and A."EMID4">0
		) A`, opdtEx)
	err = tx.Exec(sqlstr, strconv.Itoa(userID), OPDT, backdate, backdate, userID, runID, backdate, backdate, userID, runID, backdate, backdate, userID, runID, backdate, backdate, userID, runID).Error
	if err != nil {
		return err
	}
	var acid, emid1, emid2, emid3 int
	var dsvl1, dsvl2, dsvl3 float64
	sqlstr = `select "ACID","EMID1" ,"DSVL1","EMID2" ,"DSVL2","EMID3" ,"DSVL3"  from "T_INDI_CLIE_LOAN_DIVI" where "FRID"=?`
	err = tx.Raw(sqlstr, runID).Row().Scan(&acid, &emid1, &dsvl1, &emid2, &dsvl2, &emid3, &dsvl3)
	if err != nil {
		return err
	}
	err = base.SetDiviMap(base.IndiLoan, acid, emid1, dsvl1, emid2, dsvl2, emid3, dsvl3)
	if err != nil {
		return err
	}
	var tableName = "T_INDI_CLIE_LOAN_DIVI"
	var tableNameHis = "T_INDI_CLIE_LOAN_DIVI_HIS"
	err = InsertHistory(tx, runID, tableName, tableNameHis)
	if err != nil {
		return err
	}
	sqlstr = `INSERT INTO JOIN_INDI_LOAN_ISDIVI(ACID,ISRD)
	SELECT ? ACID,1 ISRD`
	base.CHDB.Exec(sqlstr, acid)
	return nil
}
func IndiLoanUpdateWFCBF(tx *gorm.DB, runID int, userID int) (err error) {
	bdate, err := base.GetBackDATE()
	if err != nil {
		return err
	}
	backdate := bdate.Format("2006-01-02")
	OPDT := time.Now()
	eng := "ENGINE=MEMORY DEFAULT CHARSET=utf8;"
	if base.AppConf.Database.Mysql == "" {
		eng = ""
	}
	//创建内存表
	sqlstr := fmt.Sprintf(`CREATE TABLE IF NOT EXISTS "TMP_NOZB"(
		"ACID" int,
		"EMID" int,
		"DSVL" decimal(16,4),
		"DSDT" date,
		"DSEM" varchar(20)
	)%s`, eng)
	err = tx.Exec(sqlstr).Error
	if err != nil {
		return err
	}
	sqlstr = `INSERT INTO "TMP_NOZB"("ACID","EMID","DSVL","DSDT","DSEM")
	SELECT DISTINCT "ACID","EMID","DSVL","DSDT",? "DSEM"
		FROM (SELECT A."ACID" "ACID",A."EMID1" "EMID",A."DSVL1"/100 "DSVL",CASE WHEN A."DSDT" < ? THEN ? ELSE A."DSDT" END "DSDT"
				FROM "T_INDI_CLIE_LOAN_DIVI2" A INNER JOIN "T_FLOW_RUN_STEP" S ON A."FRID"=S."RUNID"
				WHERE S."EMID"=? AND A."FRID"=? AND A."DSVL1">0 and A."EMID1">0
		UNION ALL
		SELECT A."ACID" "ACID",A."EMID2" "EMID",A."DSVL2"/100 "DSVL",CASE WHEN A."DSDT" < ? THEN ? ELSE A."DSDT" END "DSDT"
				FROM "T_INDI_CLIE_LOAN_DIVI2" A INNER JOIN "T_FLOW_RUN_STEP" S ON A."FRID"=S."RUNID"
				WHERE S."EMID"=? AND A."FRID"=? AND A."DSVL2">0 and A."EMID2">0
		UNION ALL
		SELECT A."ACID" "ACID",A."EMID3" "EMID",A."DSVL3"/100 "DSVL",CASE WHEN A."DSDT" < ? THEN ? ELSE A."DSDT" END "DSDT"
				FROM "T_INDI_CLIE_LOAN_DIVI2" A INNER JOIN "T_FLOW_RUN_STEP" S ON A."FRID"=S."RUNID"
				WHERE S."EMID"=? AND A."FRID"=? AND A."DSVL3">0 and A."EMID3">0
		UNION ALL
		SELECT A."ACID" "ACID",A."EMID4" "EMID",A."DSVL4"/100 "DSVL",CASE WHEN A."DSDT" < ? THEN ? ELSE A."DSDT" END "DSDT"
				FROM "T_INDI_CLIE_LOAN_DIVI2" A INNER JOIN "T_FLOW_RUN_STEP" S ON A."FRID"=S."RUNID"
				WHERE S."EMID"=? AND A."FRID"=? AND A."DSVL4">0 and A."EMID4">0
		) A`
	err = tx.Exec(sqlstr, strconv.Itoa(userID), backdate, backdate, userID, runID, backdate, backdate, userID, runID, backdate, backdate, userID, runID, backdate, backdate, userID, runID).Error
	if err != nil {
		return err
	}
	if base.AppConf.Database.Mysql != "" {
		sqlstr = `UPDATE T_INDI_LOAN_DIVI A,TMP_NOZB B
		SET WODT=B.DSDT,ISWO=CASE WHEN A.DSDT<B.DSDT THEN 0 ELSE 1 END
		WHERE A.ACID=B.ACID AND A.ISWO=0 AND (A.WODT IS NULL OR A.WODT>B.DSDT)`
	} else {
		sqlstr = `UPDATE "T_INDI_LOAN_DIVI" A SET "WODT"=B."DSDT","ISWO"=CASE WHEN A."DSDT"<B."DSDT" THEN 0 ELSE 1 END
		from "TMP_NOZB" B
		WHERE A."ACID"=B."ACID" AND A."ISWO"=0 AND (A."WODT" IS NULL OR A."WODT">B."DSDT")`
	}
	err = tx.Exec(sqlstr).Error
	if err != nil {
		return err
	}
	var opdtEx string
	if base.AppConf.Database.Mysql != "" {
		opdtEx = "cast(? as datetime)"
	} else {
		opdtEx = "cast(? as timestamp)"
	}
	sqlstr = fmt.Sprintf(`INSERT INTO "T_INDI_LOAN_DIVI"("ACID","DSTY","EMID","DSVL","DSDT","DSEM","OPDT")
	SELECT "ACID",1 "DSTY",B."EMID",B."DSVL" "DSVL",B."DSDT","DSEM",%s "OPDT"
	FROM "TMP_NOZB" B`, opdtEx)
	err = tx.Exec(sqlstr, OPDT).Error
	if err != nil {
		return err
	}
	var acid, emid1, emid2, emid3 int
	var dsvl1, dsvl2, dsvl3 float64
	sqlstr = `select "ACID","EMID1" ,"DSVL1","EMID2" ,"DSVL2","EMID3" ,"DSVL3"  from "T_INDI_CLIE_LOAN_DIVI2" where "FRID"=?`
	err = tx.Raw(sqlstr, runID).Row().Scan(&acid, &emid1, &dsvl1, &emid2, &dsvl2, &emid3, &dsvl3)
	if err != nil {
		return err
	}
	err = base.SetDiviMap(base.IndiLoan, acid, emid1, dsvl1, emid2, dsvl2, emid3, dsvl3)
	if err != nil {
		return err
	}
	var tableName = "T_INDI_CLIE_LOAN_DIVI2"
	var tableNameHis = "T_INDI_CLIE_LOAN_DIVI2_HIS"
	err = InsertHistory(tx, runID, tableName, tableNameHis)
	if err != nil {
		return err
	}
	sqlstr = `DROP TABLE "TMP_NOZB"`
	return tx.Exec(sqlstr).Error
}
func BizFeeNewWFCBF(tx *gorm.DB, runID int, userID int) (err error) {
	OPDT := time.Now()
	var opdtEx string
	if base.AppConf.Database.Mysql != "" {
		opdtEx = "cast(? as datetime)"
	} else {
		opdtEx = "cast(? as timestamp)"
	}
	sqlstr := fmt.Sprintf(`INSERT INTO "T_CM_BIZ_FEE_DIVI"("JLID","EMID","DSVL","OPDT","DSEM")
	SELECT DISTINCT "JLID","EMID","DSVL",%s "OPDT",? "DSEM"
		FROM (SELECT A."JLID" "JLID",A."EMID1" "EMID",A."DSVL1" "DSVL"
				FROM "T_COMP_ZSCLIE_DIVI" A INNER JOIN "T_FLOW_RUN_STEP" S ON A."FRID"=S."RUNID"
				WHERE S."EMID"=? AND A."FRID"=? AND A."EMID1">0
		UNION ALL
		SELECT A."JLID" "JLID",A."EMID2" "EMID",A."DSVL2" "DSVL"
				FROM "T_COMP_ZSCLIE_DIVI" A INNER JOIN "T_FLOW_RUN_STEP" S ON A."FRID"=S."RUNID"
				WHERE S."EMID"=? AND A."FRID"=? AND A."EMID2">0
		UNION ALL
		SELECT A."JLID" "JLID",A."EMID3" "EMID",A."DSVL3" "DSVL"
				FROM "T_COMP_ZSCLIE_DIVI" A INNER JOIN "T_FLOW_RUN_STEP" S ON A."FRID"=S."RUNID"
				WHERE S."EMID"=? AND A."FRID"=? AND A."EMID3">0
		UNION ALL
		SELECT A."JLID" "JLID",A."EMID4" "EMID",A."DSVL4" "DSVL"
				FROM "T_COMP_ZSCLIE_DIVI" A INNER JOIN "T_FLOW_RUN_STEP" S ON A."FRID"=S."RUNID"
				WHERE S."EMID"=? AND A."FRID"=? AND A."EMID4">0
		UNION ALL
		SELECT A."JLID" "JLID",A."EMID5" "EMID",A."DSVL5" "DSVL"
				FROM "T_COMP_ZSCLIE_DIVI" A INNER JOIN "T_FLOW_RUN_STEP" S ON A."FRID"=S."RUNID"
				WHERE S."EMID"=? AND A."FRID"=? AND A."EMID5">0
		UNION ALL
		SELECT A."JLID" "JLID",A."EMID6" "EMID",A."DSVL6" "DSVL"
				FROM "T_COMP_ZSCLIE_DIVI" A INNER JOIN "T_FLOW_RUN_STEP" S ON A."FRID"=S."RUNID"
				WHERE S."EMID"=? AND A."FRID"=? AND A."EMID6">0
		UNION ALL
		SELECT A."JLID" "JLID",A."EMID7" "EMID",A."DSVL7" "DSVL"
				FROM "T_COMP_ZSCLIE_DIVI" A INNER JOIN "T_FLOW_RUN_STEP" S ON A."FRID"=S."RUNID"
				WHERE S."EMID"=? AND A."FRID"=? AND A."EMID7">0
		UNION ALL
		SELECT A."JLID" "JLID",A."EMID8" "EMID",A."DSVL8" "DSVL"
				FROM "T_COMP_ZSCLIE_DIVI" A INNER JOIN "T_FLOW_RUN_STEP" S ON A."FRID"=S."RUNID"
				WHERE S."EMID"=? AND A."FRID"=? AND A."EMID8">0
		UNION ALL
		SELECT A."JLID" "JLID",A."EMID9" "EMID",A."DSVL9" "DSVL"
				FROM "T_COMP_ZSCLIE_DIVI" A INNER JOIN "T_FLOW_RUN_STEP" S ON A."FRID"=S."RUNID"
				WHERE S."EMID"=? AND A."FRID"=? AND A."EMID9">0
		UNION ALL
		SELECT A."JLID" "JLID",A."EMID10" "EMID",A."DSVL10" "DSVL"
				FROM "T_COMP_ZSCLIE_DIVI" A INNER JOIN "T_FLOW_RUN_STEP" S ON A."FRID"=S."RUNID"
				WHERE S."EMID"=? AND A."FRID"=? AND A."EMID10">0
		UNION ALL
		SELECT A."JLID" "JLID",A."EMID11" "EMID",A."DSVL11" "DSVL"
				FROM "T_COMP_ZSCLIE_DIVI" A INNER JOIN "T_FLOW_RUN_STEP" S ON A."FRID"=S."RUNID"
				WHERE S."EMID"=? AND A."FRID"=? AND A."EMID11">0
		UNION ALL
		SELECT A."JLID" "JLID",A."EMID12" "EMID",A."DSVL12" "DSVL"
				FROM "T_COMP_ZSCLIE_DIVI" A INNER JOIN "T_FLOW_RUN_STEP" S ON A."FRID"=S."RUNID"
				WHERE S."EMID"=? AND A."FRID"=? AND A."EMID12">0
		UNION ALL
		SELECT A."JLID" "JLID",A."EMID13" "EMID",A."DSVL13" "DSVL"
				FROM "T_COMP_ZSCLIE_DIVI" A INNER JOIN "T_FLOW_RUN_STEP" S ON A."FRID"=S."RUNID"
				WHERE S."EMID"=? AND A."FRID"=? AND A."EMID13">0
		UNION ALL
		SELECT A."JLID" "JLID",A."EMID14" "EMID",A."DSVL14" "DSVL"
				FROM "T_COMP_ZSCLIE_DIVI" A INNER JOIN "T_FLOW_RUN_STEP" S ON A."FRID"=S."RUNID"
				WHERE S."EMID"=? AND A."FRID"=? AND A."EMID14">0
		UNION ALL
		SELECT A."JLID" "JLID",A."EMID15" "EMID",A."DSVL15" "DSVL"
				FROM "T_COMP_ZSCLIE_DIVI" A INNER JOIN "T_FLOW_RUN_STEP" S ON A."FRID"=S."RUNID"
				WHERE S."EMID"=? AND A."FRID"=? AND A."EMID15">0
		) A`, opdtEx)
	err = tx.Exec(sqlstr, OPDT, strconv.Itoa(userID), userID, runID, userID, runID, userID, runID, userID, runID, userID, runID, userID, runID, userID, runID, userID, runID, userID, runID, userID, runID, userID, runID, userID, runID, userID, runID, userID, runID, userID, runID).Error
	if err != nil {
		return err
	}
	var jlid int
	sqlstr = `select "JLID" from "T_COMP_ZSCLIE_DIVI" where "FRID"=?`
	err = tx.Raw(sqlstr, runID).Row().Scan(&jlid)
	if err != nil {
		return err
	}
	var tableName = "T_COMP_ZSCLIE_DIVI"
	var tableNameHis = "T_COMP_ZSCLIE_DIVI_HIS"
	err = InsertHistory(tx, runID, tableName, tableNameHis)
	if err != nil {
		return err
	}
	sqlstr = `INSERT INTO JOIN_CM_BIZ_FEE_ISDIVI(JLID,ISRD)
	SELECT ? JLID,1 ISRD`
	base.CHDB.Exec(sqlstr, jlid)
	return nil
}
func BizFeeUpdateWFCBF(tx *gorm.DB, runID int, userID int) (err error) {
	OPDT := time.Now()
	var opdtEx string
	if base.AppConf.Database.Mysql != "" {
		opdtEx = "cast(? as datetime)"
	} else {
		opdtEx = "cast(? as timestamp)"
	}
	sqlstr := fmt.Sprintf(`UPDATE "T_CM_BIZ_FEE_DIVI" SET "ISWO"=1,"WOEM"=?,"OPDT"=%s
	WHERE "JLID" IN(SELECT "JLID" FROM "T_COMP_ZSCLIE_DIVI2" A INNER JOIN "T_FLOW_RUN_STEP" S ON A."FRID"=S."RUNID" WHERE S."EMID"=? AND A."FRID"=?)
	AND "ISWO"=0`, opdtEx)
	err = tx.Exec(sqlstr, strconv.Itoa(userID), OPDT, userID, runID).Error
	if err != nil {
		return err
	}
	sqlstr = fmt.Sprintf(`INSERT INTO "T_CM_BIZ_FEE_DIVI"("JLID","EMID","DSVL","OPDT","DSEM")
	SELECT DISTINCT "JLID","EMID","DSVL",%s "OPDT",? "DSEM"
		FROM (SELECT A."JLID" "JLID",A."EMID1" "EMID",A."DSVL1" "DSVL"
				FROM "T_COMP_ZSCLIE_DIVI2" A INNER JOIN "T_FLOW_RUN_STEP" S ON A."FRID"=S."RUNID"
				WHERE S."EMID"=? AND A."FRID"=? AND A."EMID1">0
		UNION ALL
		SELECT A."JLID" "JLID",A."EMID2" "EMID",A."DSVL2" "DSVL"
				FROM "T_COMP_ZSCLIE_DIVI2" A INNER JOIN "T_FLOW_RUN_STEP" S ON A."FRID"=S."RUNID"
				WHERE S."EMID"=? AND A."FRID"=? AND A."EMID2">0
		UNION ALL
		SELECT A."JLID" "JLID",A."EMID3" "EMID",A."DSVL3" "DSVL"
				FROM "T_COMP_ZSCLIE_DIVI2" A INNER JOIN "T_FLOW_RUN_STEP" S ON A."FRID"=S."RUNID"
				WHERE S."EMID"=? AND A."FRID"=? AND A."EMID3">0
		UNION ALL
		SELECT A."JLID" "JLID",A."EMID4" "EMID",A."DSVL4" "DSVL"
				FROM "T_COMP_ZSCLIE_DIVI2" A INNER JOIN "T_FLOW_RUN_STEP" S ON A."FRID"=S."RUNID"
				WHERE S."EMID"=? AND A."FRID"=? AND A."EMID4">0
		UNION ALL
		SELECT A."JLID" "JLID",A."EMID5" "EMID",A."DSVL5" "DSVL"
				FROM "T_COMP_ZSCLIE_DIVI2" A INNER JOIN "T_FLOW_RUN_STEP" S ON A."FRID"=S."RUNID"
				WHERE S."EMID"=? AND A."FRID"=? AND A."EMID5">0
		UNION ALL
		SELECT A."JLID" "JLID",A."EMID6" "EMID",A."DSVL6" "DSVL"
				FROM "T_COMP_ZSCLIE_DIVI2" A INNER JOIN "T_FLOW_RUN_STEP" S ON A."FRID"=S."RUNID"
				WHERE S."EMID"=? AND A."FRID"=? AND A."EMID6">0
		UNION ALL
		SELECT A."JLID" "JLID",A."EMID7" "EMID",A."DSVL7" "DSVL"
				FROM "T_COMP_ZSCLIE_DIVI2" A INNER JOIN "T_FLOW_RUN_STEP" S ON A."FRID"=S."RUNID"
				WHERE S."EMID"=? AND A."FRID"=? AND A."EMID7">0
	    UNION ALL
		SELECT A."JLID" "JLID",A."EMID8" "EMID",A."DSVL8" "DSVL"
				FROM "T_COMP_ZSCLIE_DIVI2" A INNER JOIN "T_FLOW_RUN_STEP" S ON A."FRID"=S."RUNID"
				WHERE S."EMID"=? AND A."FRID"=? AND A."EMID8">0
		UNION ALL
		SELECT A."JLID" "JLID",A."EMID9" "EMID",A."DSVL9" "DSVL"
				FROM "T_COMP_ZSCLIE_DIVI2" A INNER JOIN "T_FLOW_RUN_STEP" S ON A."FRID"=S."RUNID"
				WHERE S."EMID"=? AND A."FRID"=? AND A."EMID9">0
		UNION ALL
		SELECT A."JLID" "JLID",A."EMID10" "EMID",A."DSVL10" "DSVL"
				FROM "T_COMP_ZSCLIE_DIVI2" A INNER JOIN "T_FLOW_RUN_STEP" S ON A."FRID"=S."RUNID"
				WHERE S."EMID"=? AND A."FRID"=? AND A."EMID10">0
		UNION ALL
		SELECT A."JLID" "JLID",A."EMID11" "EMID",A."DSVL11" "DSVL"
				FROM "T_COMP_ZSCLIE_DIVI2" A INNER JOIN "T_FLOW_RUN_STEP" S ON A."FRID"=S."RUNID"
				WHERE S."EMID"=? AND A."FRID"=? AND A."EMID11">0
		UNION ALL
		SELECT A."JLID" "JLID",A."EMID12" "EMID",A."DSVL12" "DSVL"
				FROM "T_COMP_ZSCLIE_DIVI2" A INNER JOIN "T_FLOW_RUN_STEP" S ON A."FRID"=S."RUNID"
				WHERE S."EMID"=? AND A."FRID"=? AND A."EMID12">0
		UNION ALL
		SELECT A."JLID" "JLID",A."EMID13" "EMID",A."DSVL13" "DSVL"
				FROM "T_COMP_ZSCLIE_DIVI2" A INNER JOIN "T_FLOW_RUN_STEP" S ON A."FRID"=S."RUNID"
				WHERE S."EMID"=? AND A."FRID"=? AND A."EMID13">0
		UNION ALL
		SELECT A."JLID" "JLID",A."EMID14" "EMID",A."DSVL14" "DSVL"
				FROM "T_COMP_ZSCLIE_DIVI2" A INNER JOIN "T_FLOW_RUN_STEP" S ON A."FRID"=S."RUNID"
				WHERE S."EMID"=? AND A."FRID"=? AND A."EMID14">0
		UNION ALL
		SELECT A."JLID" "JLID",A."EMID15" "EMID",A."DSVL15" "DSVL"
				FROM "T_COMP_ZSCLIE_DIVI2" A INNER JOIN "T_FLOW_RUN_STEP" S ON A."FRID"=S."RUNID"
				WHERE S."EMID"=? AND A."FRID"=? AND A."EMID15">0
		) A`, opdtEx)
	err = tx.Exec(sqlstr, OPDT, strconv.Itoa(userID), userID, runID, userID, runID, userID, runID, userID, runID, userID, runID, userID, runID, userID, runID, userID, runID, userID, runID, userID, runID, userID, runID, userID, runID, userID, runID, userID, runID, userID, runID).Error
	if err != nil {
		return err
	}
	var tableName = "T_COMP_ZSCLIE_DIVI2"
	var tableNameHis = "T_COMP_ZSCLIE_DIVI2_HIS"
	err = InsertHistory(tx, runID, tableName, tableNameHis)
	if err != nil {
		return err
	}
	return
}
func YhsqWFCBF(tx *gorm.DB, runID int, userID int) (err error) {
	type User struct {
		ID         int        `gorm:"AUTO_INCREMENT;primary_key;column:ID"`
		No         string     `gorm:"column:SysUserID;size:10"`
		OrganID    int        `gorm:"column:OrganID"`
		Name       string     `gorm:"column:SysUserName;size:20"`
		Memo       string     `gorm:"column:SysUserMemo;size:500"`
		EMail      string     `gorm:"column:EMail;size:60"`
		Telephone  string     `gorm:"column:Telephone;size:30"`
		PositionID int        `gorm:"column:Position"`
		SerialID   int        `gorm:"column:Serial"`
		Sex        string     `gorm:"column:SSEX;size:1"`
		Password   string     `gorm:"column:Password"`
		IsPublic   int        `gorm:"column:ISPU"`
		RoleIds    string     `gorm:"column:RoleIds;size:100"`
		Birthday   *time.Time `gorm:"column:Birthday;type:date;"`
		STATUS     string     `gorm:"column:STATUS"`
	}
	u := User{}
	sqlStr := `select "SysUserID","SysUserName","OrganID","EMail" from "T_SP_YHSQ" where "FRID"=?`
	err = tx.Raw(sqlStr, runID).Row().Scan(&u.No, &u.Name, &u.OrganID, &u.EMail)
	if err != nil {
		return
	}
	u.Password = popedom.HashPassword(u.No, "00000000")
	u.Sex = "1"
	u.IsPublic = 0
	u.PositionID = 5
	u.SerialID = 4
	u.STATUS = "1"
	err = tx.Table("T_SysUser").Create(&u).Error
	if err != nil {
		return
	}
	err = base.CacheUser(u.ID, u.Name, u.OrganID, u.No)
	return
}
func BmbgWFCBF(tx *gorm.DB, runID int, userID int) (err error) {
	var yjbd_dg, yjbd_cx, yjbd_gd, sqr, orgidy, orgidx int
	var dddt time.Time
	sqlStr := `select "YJBD_DG" ,"YJBD_CX" ,"YJBD_GD","SQR","OrgIDy", "OrgIDx","DDDT" from "T_SP_BMBG" where "FRID"=?`
	err = tx.Raw(sqlStr, runID).Row().Scan(&yjbd_dg, &yjbd_cx, &yjbd_gd, &sqr, &orgidy, &orgidx, &dddt)
	if err != nil {
		return
	}
	err = procYgdd(tx, yjbd_dg, 1, runID, sqr, orgidy, orgidx, dddt)
	if err != nil {
		return
	}
	err = procYgdd(tx, yjbd_cx, 2, runID, sqr, orgidy, orgidx, dddt)
	if err != nil {
		return
	}
	err = procYgdd(tx, yjbd_gd, 3, runID, sqr, orgidy, orgidx, dddt)
	if err != nil {
		return
	}
	sqlStr = `update "T_SysUser" set "OrganID" =? where "ID" =?`
	err = tx.Exec(sqlStr, orgidx, sqr).Error
	if err != nil {
		return
	}
	if strings.HasSuffix(base.AppConf.CHDBName, "_sh") {
		sqlStr = `delete from "t_UserRole" where "UserId" = ? and "RoleId" in (9,3)`
		err = tx.Exec(sqlStr, sqr).Error
		if err != nil {
			return
		}
		sqlStr = `insert into "t_UserRole"("UserId","RoleId") values(?,9),(?,3)`
		err = tx.Exec(sqlStr, sqr, sqr).Error
		if err != nil {
			return
		}
	}
	err = popedom.LoadUserPermsToRedis(tx, sqr)
	return
}
func BmbgDiviVerify(tx *gorm.DB, runID int, userID int) (err error) {
	var yjbd_dg, yjbd_cx, yjbd_gd int
	sqlStr := `select "YJBD_DG" ,"YJBD_CX" ,"YJBD_GD" from "T_SP_BMBG" where "FRID"=?`
	err = tx.Raw(sqlStr, runID).Row().Scan(&yjbd_dg, &yjbd_cx, &yjbd_gd)
	if err != nil {
		return
	}
	if yjbd_dg == 1 {
		err = bmbgDiviVerifyFs1(tx, runID, 1)
	} else if yjbd_dg == 3 {
		err = bmbgDiviVerifyFs3(tx, runID, 1)
	}
	if err != nil {
		return
	}
	if yjbd_cx == 1 {
		err = bmbgDiviVerifyFs1(tx, runID, 2)
	} else if yjbd_cx == 3 {
		err = bmbgDiviVerifyFs3(tx, runID, 2)
	}
	if err != nil {
		return
	}
	if yjbd_gd == 1 {
		err = bmbgDiviVerifyFs1(tx, runID, 3)
	} else if yjbd_gd == 3 {
		err = bmbgDiviVerifyFs3(tx, runID, 3)
	}
	return
}
func YglzDiviVerify(tx *gorm.DB, runID int, userID int) (err error) {
	var yjbd_dg, yjbd_cx, yjbd_gd int
	sqlStr := `select "YJBD_DG" ,"YJBD_CX" ,"YJBD_GD" from "T_SP_YGLZ" where "FRID"=?`
	err = tx.Raw(sqlStr, runID).Row().Scan(&yjbd_dg, &yjbd_cx, &yjbd_gd)
	if err != nil {
		return
	}
	if yjbd_dg == 1 {
		err = bmbgDiviVerifyFs1(tx, runID, 1)
	} else if yjbd_dg == 3 {
		err = bmbgDiviVerifyFs3(tx, runID, 1)
	}
	if err != nil {
		return
	}
	if yjbd_cx == 1 {
		err = bmbgDiviVerifyFs1(tx, runID, 2)
	} else if yjbd_cx == 3 {
		err = bmbgDiviVerifyFs3(tx, runID, 2)
	}
	if err != nil {
		return
	}
	if yjbd_gd == 1 {
		err = bmbgDiviVerifyFs1(tx, runID, 3)
	} else if yjbd_gd == 3 {
		err = bmbgDiviVerifyFs3(tx, runID, 3)
	}
	return
}
func bmbgDiviVerifyFs1(tx *gorm.DB, runID int, ywlx int) (err error) {
	var msg string
	if ywlx == 1 {
		msg = "对公存贷款"
	} else if ywlx == 2 {
		msg = "储蓄"
	} else {
		msg = "个贷"
	}
	var num float64
	sqlStr := `select sum("DSVL") from "T_SP_BMBG_TOEMPS" where "SPID" =? AND "YWLX" =?`
	err = tx.Raw(sqlStr, runID, ywlx).Row().Scan(&num)
	if err != nil || math.Abs(num-100) > 0.1 {
		err = fmt.Errorf("%s认定关系之和必须等于100", msg)
	}
	return
}
func bmbgDiviVerifyFs3(tx *gorm.DB, runID int, ywlx int) (err error) {
	var msg, sqlStr, fn string
	if base.AppConf.Database.Mysql != "" {
		fn = "IFNULL"
	} else {
		fn = "COALESCE"
	}
	if ywlx == 1 {
		msg = "对公存贷款"
		sqlStr = fmt.Sprintf(`select count(*) from "T_SP_BMBG_COMP_ACCO_DIVI" where "SPID" =? AND %s("DSVL1",0)+%s("DSVL2",0)+%s("DSVL3",0)+%s("DSVL4",0)+%s("DSVL5",0)+%s("DSVL6",0)=0`, fn, fn, fn, fn, fn, fn)
	} else if ywlx == 2 {
		msg = "储蓄"
		sqlStr = fmt.Sprintf(`select count(*) from "T_SP_BMBG_INDI_ACCO_DIVI" where "SPID" =? AND %s("DSVL1",0)+%s("DSVL2",0)+%s("DSVL3",0)+%s("DSVL4",0)=0`, fn, fn, fn, fn)
	} else {
		msg = "个贷"
		sqlStr = fmt.Sprintf(`select count(*) from "T_SP_BMBG_INDI_LOAN_DIVI" where "SPID" =? AND %s("DSVL1",0)+%s("DSVL2",0)+%s("DSVL3",0)+%s("DSVL4",0)=0`, fn, fn, fn, fn)
	}
	var num int
	err = tx.Raw(sqlStr, runID).Row().Scan(&num)
	if err != nil {
		return
	}
	if num > 0 {
		err = fmt.Errorf("%s认定关系存在没有认定的账户,请检查", msg)
	}
	return
}
func procYgdd(tx *gorm.DB, yjbb int, ywlx int, runID int, sqr int, orgidy int, orgidx int, dddt time.Time) (err error) {
	var tname string
	if ywlx == 1 {
		tname = "T_COMP_ACCO_DIVI"
	} else if ywlx == 2 {
		tname = "T_INDI_ACCO_DIVI"
	} else {
		tname = "T_INDI_LOAN_DIVI"
	}
	bdate, err := base.GetBackDATE()
	if err != nil {
		return err
	}
	if dddt.Unix() < bdate.Unix() {
		err = fmt.Errorf("申请没有及时处理，调动日期%s不能小于系统可追溯日期%s", dddt.Format("20060102"), bdate.Format("20060102"))
		return
	}
	dddtStr := dddt.Format("2006-01-02")
	var eng, dddt2db string
	if base.AppConf.Database.Mysql != "" {
		eng = "ENGINE=MEMORY DEFAULT CHARSET=utf8;"
		dddt2db = fmt.Sprintf("'%s'", dddtStr)
	} else {
		eng = ""
		dddt2db = fmt.Sprintf("to_timestamp('%s','yyyy-mm-dd')", dddtStr)
	}
	var sqlstr string
	//方式2
	if yjbb == 2 {
		sqlstr = fmt.Sprintf(`UPDATE "%s" SET "DPID"=?,"TMST"=now() WHERE "EMID"=? and "ISWO"=0 and "WODT" is null and "DSDT">=?`, tname)
		err = tx.Exec(sqlstr, orgidx, sqr, dddt).Error
		if err != nil {
			return err
		}
		sqlstr = fmt.Sprintf(`UPDATE "%s" SET "DPID"=? WHERE "EMID"=? and "ISWO"=0 and "WODT" is null and "DSDT"<?`, tname)
		err = tx.Exec(sqlstr, orgidy, sqr, dddt).Error
		if err != nil {
			return err
		}
		return
	}
	//创建内存表
	sqlstr = fmt.Sprintf(`CREATE TABLE IF NOT EXISTS "TMP_NOZB"(
		"ACID" int,
		"EMID" int,
		"DSVL" decimal(16,4),
		"DSDT" date,
		"DSEM" varchar(20)
	)%s`, eng)
	err = tx.Exec(sqlstr).Error
	if err != nil {
		return err
	}
	sqlstr = `TRUNCATE TABLE "TMP_NOZB"`
	err = tx.Exec(sqlstr).Error
	if err != nil {
		return err
	}
	sqlstr = fmt.Sprintf(`INSERT INTO "TMP_NOZB"("ACID","EMID","DSVL","DSDT","DSEM")
              SELECT "ACID","EMID",sum("DSVL"),? "DSDT",'YGDD'
			  FROM "%s"
			  WHERE "EMID"=? AND "ISWO"=0 and ("WODT" is null or "WODT">?)
			  GROUP BY "ACID","EMID"`, tname)
	err = tx.Exec(sqlstr, dddtStr, sqr, dddtStr).Error
	if err != nil {
		return err
	}
	if base.AppConf.Database.Mysql != "" {
		sqlstr = fmt.Sprintf(`UPDATE %s A,TMP_NOZB B
		SET WODT=B.DSDT,ISWO=CASE WHEN A.DSDT<B.DSDT THEN 0 ELSE 1 END,DPID=?
		WHERE A.ACID=B.ACID AND A.ISWO=0 AND (A.WODT IS NULL OR A.WODT>B.DSDT)`, tname)
	} else {
		sqlstr = fmt.Sprintf(`UPDATE "%s" A SET "WODT"=B."DSDT","ISWO"=CASE WHEN A."DSDT"<B."DSDT" THEN 0 ELSE 1 END,"DPID"=?
		from "TMP_NOZB" B
		WHERE A."ACID"=B."ACID" AND A."ISWO"=0 AND (A."WODT" IS NULL OR A."WODT">B."DSDT")`, tname)
	}
	err = tx.Exec(sqlstr, orgidy).Error
	if err != nil {
		return err
	}
	if yjbb == 0 {
		sqlstr = fmt.Sprintf(`INSERT INTO "%s"("ACID","DSTY","EMID","DSVL","DSDT","DSEM","DPID")
		SELECT "ACID",1 "DSTY",B."EMID",B."DSVL" "DSVL",B."DSDT","DSEM",? DPID
		FROM  "TMP_NOZB" B`, tname)
		err = tx.Exec(sqlstr, orgidx).Error
		if err != nil {
			return err
		}
	} else if yjbb == 1 {
		sqlstr = fmt.Sprintf(`INSERT INTO "%s"("ACID","DSTY","EMID","DSVL","DSDT","DSEM","DPID")
		SELECT "ACID",1 "DSTY",A."EMID",A."DSVL"/100*B."DSVL",B."DSDT","DSEM",0 DPID
		FROM (select "EMID","DSVL" from "T_SP_BMBG_TOEMPS" where "SPID"=? and "YWLX"=?) A CROSS JOIN
		"TMP_NOZB" B`, tname)
		err = tx.Exec(sqlstr, runID, ywlx).Error
		if err != nil {
			return err
		}
	} else if yjbb == 3 {
		diviTable := "T_SP_BMBG" + tname[1:]
		count := 4
		if tname == "T_COMP_ACCO_DIVI" {
			count = 6
		}
		var buff bytes.Buffer
		buff.WriteString(fmt.Sprintf(`INSERT INTO "%s"("ACID","DSTY","EMID","DSVL","DSDT","DSEM","DPID")`, tname))
		for i := 1; i <= count; i++ {
			buff.WriteString(fmt.Sprintf(` SELECT "ACID",1 "DSTY","EMID%d","DSVL%d"/100,%s,'YGDD',0
			FROM  "%s"
			WHERE "SPID"=%d AND "DSVL%d">0 AND "EMID%d">0`, i, i, dddt2db, diviTable, runID, i, i))
			if i < count {
				buff.WriteString(" UNION ALL ")
			}
		}
		err = tx.Exec(buff.String()).Error
		if err != nil {
			return err
		}
	} else {
		err = fmt.Errorf("无效的yjbb:%d", yjbb)
		return
	}
	return
}
func YglzWFCBF(tx *gorm.DB, runID int, userID int) (err error) {
	var yjbd_dg, yjbd_cx, yjbd_gd, sqr, dpid int
	var dddt time.Time
	sqlStr := `select "YJBD_DG","YJBD_CX","YJBD_GD","EMID","DPID","SQSJ" from "T_SP_YGLZ" where "FRID"=?`
	err = tx.Raw(sqlStr, runID).Row().Scan(&yjbd_dg, &yjbd_cx, &yjbd_gd, &sqr, &dpid, &dddt)
	if err != nil {
		return
	}
	err = procYgdd(tx, yjbd_dg, 1, runID, sqr, dpid, dpid, dddt)
	if err != nil {
		return
	}
	err = procYgdd(tx, yjbd_cx, 2, runID, sqr, dpid, dpid, dddt)
	if err != nil {
		return
	}
	err = procYgdd(tx, yjbd_gd, 3, runID, sqr, dpid, dpid, dddt)
	if err != nil {
		return
	}
	var dpid2 int
	sqlStr = `select "ID" from "T_Organization" where "OrganName" like '%离职%'`
	err = tx.Raw(sqlStr).Row().Scan(&dpid2)
	if err != nil || dpid2 == 0 {
		err = fmt.Errorf("没有找到名称含有的离职部门:%s", err.Error())
		return
	}
	sqlStr = `update "T_SysUser" set "OrganID" =? where "ID" =?`
	err = tx.Exec(sqlStr, dpid2, sqr).Error
	if err != nil {
		return
	}
	sqlStr = `update "T_SysUser" set "Password" ='00000000' where "ID" =?`
	err = tx.Exec(sqlStr, sqr).Error
	return
}
func initExtent() {
	callBackFuncMap["CompNewWFCBF"] = CompNewWFCBF
	callBackFuncMap["CompUpdateWFCBF"] = CompUpdateWFCBF
	callBackFuncMap["IndiSaveNewWFCBF"] = IndiSaveNewWFCBF
	callBackFuncMap["IndiSaveUpdateWFCBF"] = IndiSaveUpdateWFCBF
	callBackFuncMap["IndiLoanNewWFCBF"] = IndiLoanNewWFCBF
	callBackFuncMap["IndiLoanUpdateWFCBF"] = IndiLoanUpdateWFCBF
	callBackFuncMap["BizFeeNewWFCBF"] = BizFeeNewWFCBF
	callBackFuncMap["BizFeeUpdateWFCBF"] = BizFeeUpdateWFCBF
	callBackFuncMap["YhsqWFCBF"] = YhsqWFCBF
	callBackFuncMap["BmbgWFCBF"] = BmbgWFCBF
	callBackFuncMap["YglzWFCBF"] = YglzWFCBF
	callBackFuncMap["BmbgDiviVerify"] = BmbgDiviVerify
	callBackFuncMap["YglzDiviVerify"] = YglzDiviVerify
	executorExcludePool["NoHaveCompDivi"] = NoHaveCompDivi
	executorExcludePool["NoHaveIndiAccoDivi"] = NoHaveIndiAccoDivi
	executorExcludePool["NoHaveIndiGtwhDivi"] = NoHaveIndiGtwhDivi
	emidsFuncPool["getCompCuidEmids"] = GetCompCuidEmids
	emidsFuncPool["getIndiCuidEmids"] = GetIndiCuidEmids
	emidsFuncPool["getIndiLoanAcidEmids"] = GetIndiLoanAcidEmids
	emidsFuncPool["getCompZsJlidEmids"] = GetCompZsJlidEmids
	emidsFuncPool["getTXGLY"] = GetTXGLY
	emidsFuncPool["getTXFZR"] = getTXFZR
}

var emidsFuncPool = make(map[string]GetEmidsFunc, 10)

type GetEmidsFunc func(tx *gorm.DB, runid int) ([]int, error)

func GetIndiCuidEmids(tx *gorm.DB, runid int) ([]int, error) {
	sql := `select "CUID" from "T_INDI_CLIE_DIVI2" WHERE "FRID"=?`
	row := tx.Raw(sql, runid).Row()
	var cuid int
	if err := row.Scan(&cuid); err != nil {
		return nil, err
	}
	if cuid == 0 {
		return nil, nil
	}
	sql = "select ID from T_INDI_ACCO where CUID=?"
	rows, err := base.CHDB.Raw(sql, cuid).Rows()
	if err != nil {
		return nil, err
	}
	acids := make([]int, 0, 10)
	for rows.Next() {
		var acid int
		rows.Scan(&acid)
		acids = append(acids, acid)
	}
	rows.Close()
	sql = `SELECT DISTINCT "EMID" FROM "T_INDI_ACCO_DIVI" WHERE "ISWO"=0 AND "WODT" IS NULL AND "ACID" in (?)`
	rows, err = tx.Raw(sql, acids).Rows()
	if err != nil {
		return nil, err
	}
	defer rows.Close()
	emids := make([]int, 0, 5)
	for rows.Next() {
		var emid int
		rows.Scan(&emid)
		emids = append(emids, emid)
	}
	return emids, nil
}

func GetCompCuidEmids(tx *gorm.DB, runid int) ([]int, error) {
	sql := `select "ACID" from "T_COMP_CLIE_DIVI2" WHERE "FRID"=?`
	row := tx.Raw(sql, runid).Row()
	var acid int
	if err := row.Scan(&acid); err != nil {
		return nil, err
	}
	if acid == 0 {
		return nil, nil
	}
	sql = `SELECT DISTINCT "EMID" FROM "T_COMP_ACCO_DIVI" WHERE "ACID"=? AND "ISWO"=0 AND "WODT" IS NULL`
	rows, err := tx.Raw(sql, acid).Rows()
	if err != nil {
		return nil, err
	}
	defer rows.Close()
	emids := make([]int, 0, 6)
	for rows.Next() {
		var emid int
		rows.Scan(&emid)
		emids = append(emids, emid)
	}
	return emids, nil
}

func GetCompZsJlidEmids(tx *gorm.DB, runid int) ([]int, error) {
	sql := `select "JLID" from "T_COMP_ZSCLIE_DIVI2" WHERE "FRID"=?`
	row := tx.Raw(sql, runid).Row()
	var jlid int
	if err := row.Scan(&jlid); err != nil {
		return nil, err
	}
	if jlid == 0 {
		return nil, nil
	}
	sql = `SELECT DISTINCT "EMID" FROM "T_CM_BIZ_FEE_DIVI" WHERE "JLID"=? AND "ISWO"=0`
	rows, err := tx.Raw(sql, jlid).Rows()
	if err != nil {
		return nil, err
	}
	defer rows.Close()
	emids := make([]int, 0, 6)
	for rows.Next() {
		var emid int
		rows.Scan(&emid)
		emids = append(emids, emid)
	}
	return emids, nil
}

func GetIndiLoanAcidEmids(tx *gorm.DB, runid int) ([]int, error) {
	sql := `select "ACID" from "T_INDI_CLIE_LOAN_DIVI2" WHERE "FRID"=?`
	row := tx.Raw(sql, runid).Row()
	var acid int
	if err := row.Scan(&acid); err != nil {
		return nil, err
	}
	if acid == 0 {
		return nil, nil
	}
	sql = `SELECT DISTINCT "EMID" FROM "T_INDI_LOAN_DIVI" WHERE "ACID"=? AND "ISWO"=0 AND "WODT" IS NULL`
	rows, err := tx.Raw(sql, acid).Rows()
	if err != nil {
		return nil, err
	}
	defer rows.Close()
	emids := make([]int, 0, 6)
	for rows.Next() {
		var emid int
		rows.Scan(&emid)
		emids = append(emids, emid)
	}
	return emids, nil
}

func GetOrganID(tx *gorm.DB, runid int) (int, error) {
	sql := `select "OrgIDx" from "T_SP_BMBG" WHERE "FRID"=?`
	row := tx.Raw(sql, runid).Row()
	var orgid int
	if err := row.Scan(&orgid); err != nil {
		return 0, err
	}
	return orgid, nil
}

type ExecutorExcludeFunc func(tx *gorm.DB, runid int) (bool, error)

var executorExcludePool = make(map[string]ExecutorExcludeFunc, 10)

func NoHaveCompDivi(tx *gorm.DB, runid int) (bool, error) {
	sql := `select "SQR" from "T_SP_BMBG" WHERE "FRID"=?`
	row := tx.Raw(sql, runid).Row()
	var emid int
	if err := row.Scan(&emid); err != nil {
		return false, err
	}
	sql = `select count(*) from "T_COMP_ACCO_DIVI" where "EMID"=? AND "ISWO"=0 AND "WODT" IS NULL`
	row = tx.Raw(sql, emid).Row()
	var count int
	if err := row.Scan(&count); err != nil {
		return false, err
	}
	if count == 0 {
		return true, nil
	}
	return false, nil
}
func NoHaveIndiAccoDivi(tx *gorm.DB, runid int) (bool, error) {
	sql := `select "SQR" from "T_SP_BMBG" WHERE "FRID"=?`
	row := tx.Raw(sql, runid).Row()
	var emid int
	if err := row.Scan(&emid); err != nil {
		return false, err
	}
	sql = ` select count(*) from "T_INDI_ACCO_DIVI" where "EMID"=? AND "ISWO"=0 AND "WODT" IS NULL`
	row = tx.Raw(sql, emid).Row()
	var count1 int
	if err := row.Scan(&count1); err != nil {
		return false, err
	}
	sql = ` select count(*) from "T_INDI_LOAN_DIVI" where "EMID"=? AND "ISWO"=0 AND "WODT" IS NULL`
	row = tx.Raw(sql, emid).Row()
	var count2 int
	if err := row.Scan(&count2); err != nil {
		return false, err
	}
	if count1 == 0 && count2 == 0 {
		return true, nil
	}
	return false, nil
}
func NoHaveIndiGtwhDivi(tx *gorm.DB, runid int) (bool, error) {
	sql := `select "SQR" from "T_SP_BMBG" WHERE "FRID"=?`
	row := tx.Raw(sql, runid).Row()
	var emid int
	if err := row.Scan(&emid); err != nil {
		return false, err
	}
	sql = ` select count(*) from "T_INDI_CLIE_GTWH_DIVI" where "EMID"=? AND "ISWO"=0 AND "WODT" IS NULL`
	row = tx.Raw(sql, emid).Row()
	var count int
	if err := row.Scan(&count); err != nil {
		return false, err
	}
	if count == 0 {
		return true, nil
	}
	return false, nil
}

func GetTXGLY(tx *gorm.DB, runid int) ([]int, error) {
	sql := `select "JLID" from "T_COMP_ZSCLIE_DIVI" WHERE "FRID"=?`
	row := tx.Raw(sql, runid).Row()
	var jlid int
	if err := row.Scan(&jlid); err != nil {
		return nil, err
	}
	if jlid == 0 {
		return nil, nil
	}
	var tpid int
	sql = "SELECT dictGetUInt8('pas_olap_nj.DICT_MIDO_TYPE','TPID',toUInt64(ITID)) AS TPID FROM T_CM_BIZ_FEE_SUM_M WHERE JLID = ?"
	base.CHDB.Raw(sql, jlid).Row().Scan(&tpid)
	var userStr []string
	emids := make([]int, 0, 6)
	if tpid == 4 {
		//零售业务管理员
		userStr, _ = popedom.GetRoleUsersFormRedis(8)
	} else if tpid == 5 {
		//金融市场管理员
		userStr, _ = popedom.GetRoleUsersFormRedis(34)
	} else {
		//公司业务管理员
		userStr, _ = popedom.GetRoleUsersFormRedis(7)
	}
	var emid int
	for _, v := range userStr {
		emid, _ = strconv.Atoi(v)
		emids = append(emids, emid)
	}
	return emids, nil
}

func getTXFZR(tx *gorm.DB, runid int) ([]int, error) {
	sql := `select "JLID" from "T_COMP_ZSCLIE_DIVI2" WHERE "FRID"=?`
	row := tx.Raw(sql, runid).Row()
	var jlid int
	if err := row.Scan(&jlid); err != nil {
		return nil, err
	}
	if jlid == 0 {
		return nil, nil
	}
	var tpid int
	sql = "SELECT dictGetUInt8('pas_olap_nj.DICT_MIDO_TYPE','TPID',toUInt64(ITID)) AS TPID FROM T_CM_BIZ_FEE_SUM_M WHERE JLID = ?"
	base.CHDB.Raw(sql, jlid).Row().Scan(&tpid)
	var userStr []string
	emids := make([]int, 0, 6)
	if tpid == 4 {
		//零售业务负责人
		userStr, _ = popedom.GetRoleUsersFormRedis(31)
	} else if tpid == 5 {
		//金融市场负责人
		userStr, _ = popedom.GetRoleUsersFormRedis(29)
	} else {
		//公司业务负责人
		userStr, _ = popedom.GetRoleUsersFormRedis(30)
	}
	var emid int
	for _, v := range userStr {
		emid, _ = strconv.Atoi(v)
		emids = append(emids, emid)
	}
	return emids, nil
}
